home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume91
/
utilitys
/
cpublit1
/
part01
/
src
/
small.a
< prev
next >
Wrap
Text File
|
1991-05-08
|
7KB
|
262 lines
*:ts=8
******************************************************************************
* *
* SMALL.A (C) Copyright Eddy Carroll 1991 *
* ~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* *
* Replacement startup code for Lattice C V5.10a. Use instead of c.o. *
* This has many features stripped out to allow small utilities to *
* have as small a filesize as possible. If you use this, don't call *
* any stdio functions. *
* *
* In some of my earlier projects, I used a similar file called tiny.a. *
* Small.a is essentially that file but with Workbench support added. *
* avoid confusion between the two. *
* *
******************************************************************************
INCLUDE "exec/types.i"
INCLUDE "exec/execbase.i"
INCLUDE "exec/nodes.i"
INCLUDE "exec/lists.i"
INCLUDE "exec/ports.i"
INCLUDE "exec/libraries.i"
INCLUDE "exec/tasks.i"
INCLUDE "libraries/dos.i"
INCLUDE "libraries/dosextens.i"
INCLUDE "workbench/startup.i"
INCLUDE "exec/funcdef.i"
INCLUDE "exec/exec_lib.i"
INCLUDE "libraries/dos_lib.i"
MAXARGS EQU 100 ; Maximum number of command line arguments from CLI
AbsExecBase EQU 4 ; Welcome to the only fixed point in the universe
* A useful macro to let us call library routines
callsys macro
CALLLIB _LVO\1
endm
xdef XCEXIT
xdef exit
xref LinkerDB
xref _BSSBAS
xref _BSSLEN
csect text,0,0,1,2 * xref's after this are 16-bit reloc
xref main * Name of C program to start with.
start:
movem.l d1-d6/a0-a6,-(a7)
REGSIZE EQU (6+7)*4
lea REGSIZE(a7),A5 * Determine old stack pointer
move.l a0,a2 * Save command pointer
move.l d0,d2 * and command length
lea LinkerDB,a4 * Load base register
move.l AbsExecBase.W,a6
move.l a6,SysBase(A4)
move.l a7,_StackPtr(A4) * Save stack ptr
move.l a5,D0 * get top of stack
sub.l 4(a5),D0 * compute bottom
add.l #128,D0 * allow for parms overflow
move.l D0,_base(A4) * save for stack checking
lea DOSName(A4),A1
moveq.l #0,D0
callsys OpenLibrary
move.l D0,DOSBase(A4)
beq NoDos
move.l ThisTask(a6),a3 * Get our task ID
tst.l pr_CLI(a3) * Running from Workbench?
bne.s getcom * If no, skip to do CLI stuff
lea pr_MsgPort(a3),a0 * Our process port
callsys WaitPort * Wait for Workbench startup message
lea pr_MsgPort(a3),a0 * Get our message port again
callsys GetMsg * Get startup message
move.l d0,WBenchMsg(a4) * Save pointer to it
move.l d0,-(sp) * Save it as argv
moveq #0,d0 * And push argc of 0 to indicate WB
move.l d0,-(sp) *
bra cont * Skip to init BSS and start prog
*------ find command name:
getcom:
move.l pr_CLI(a3),a0
add.l a0,a0
add.l a0,a0
move.l cli_CommandName(a0),a1
add.l a1,a1
add.l a1,a1
*------ collect parameters:
move.l d2,d0 * get command line length
moveq.l #0,d1
move.b (a1)+,d1
move.l a1,_ProgramName(A4)
add.l d1,d0 * add length of command name
addq.l #1,d0 * allow for space after command
clr.w -(A7) * set null terminator for command line
addq.l #1,D0 * force to even number of bytes
andi.w #$fffe,D0 * (round up)
sub.l D0,A7 * make room on stack for command line
subq.l #2,D0
clr.w 0(A7,D0)
*------ copy command line onto stack
move.l d2,d0 * get command line length
subq.l #1,d0
add.l d1,d2
copy_line:
move.b 0(A2,D0.W),0(A7,D2.W) * copy command line to stack
subq.l #1,d2
dbf d0,copy_line
move.l d2,d0 * save offset to argv[1] - 1
clr.b 0(a7,d2.w) * Insert command name terminator
subq.l #1,d2
copy_cmd:
move.b 0(a1,d2.w),0(a7,d2.w) * copy command name to stack
dbf d2,copy_cmd
lea 1(a7,d0.w),a1 * get pointer to start of arguments
move.l a7,a2 * get pointer for argv[0]
sub.l #(MAXARGS*4),a7 * Reserve space for argv[]
move.l a7,a3 * Save ptr to base of argv (&argv[0])
move.l a2,(a7) * Setup argv[0] to point to cmd line
lea 4(a7),a2 * Init base into array at argv[1]
moveq #1,d2 * Initialise argc
*
* From here on down, A1 is pointer into command line
*
build_argv:
bsr.s getnext * Read next character from line
bcs.s doquote * If quote, handle
beq.s build_argv * If white space, skip over it
lea -1(a1),a0 * Get address of this parameter
bsr.s bumpargv * Store it to argv[] array
build_2:
bsr.s getnext * Get next character
bne.s build_2 * If not white space, keep looking
clr.b -1(a1) * Zero-terminate current argument
bra.s build_argv * And go back to get next argument
doquote:
move.l a1,a0 * Get pointer to this argument
bsr.s bumpargv * Output it to argv[]
quote_2:
bsr.s getnext * Get next character
bcc.s quote_2 * If not quote, keep looking
clr.b -1(a1) * Zero-terminate current argument
quote_3:
bsr.s getnext * Get next character
bne.s quote_3 * Skip until space reached
beq.s build_argv * Go back and read next argument
bumpargv:
move.l a0,(a2)+ * Output ptr to current argument
addq #1,d2 * Increment argc
cmpi #MAXARGS,d2 * Used up all our arguments yet?
bls.s qrts * If not, then return
moveq #110,d0 * Else set return code
bra.s exit2 * And exit
*
* Reads next character from command line. If zero, never returns, but
* drops into call to main. Else, returns, with C=1 if character is quote,
* Z=1 if character is white space.
*
getnext:
move.b (a1)+,d0 * Get character from command line
beq.s get_2 * Exit if end of line
cmp.b #34,d0 * Check if quote
beq.s isquote *
cmp.b #32,d0 * Check if space
beq.s isspace *
cmp.b #9,d0 * Or tab
beq.s isspace *
cmp.b #10,d0 * Or end of line
isspace:
andi #$1E,ccr * Clear carry flag, retaining Z
qrts rts
isquote:
ori #1,ccr * Set carry flag
andi #$FB,ccr * Clear zero flag
rts * And return
get_2:
move.l a3,-(a7) * Push argv onto stack
move.l d2,-(a7) * Push argc onto stack
cont:
lea _BSSBAS,a3 * get base of BSS
moveq #0,d1
move.l #_BSSLEN,d0 * get length of BSS in longwords
bra.s clr_lp * and clear for length given
clr_bss move.l d1,(a3)+
clr_lp dbf d0,clr_bss
domain:
jsr main(PC) * Call main(argc,argv)
moveq.l #0,d0 * Set successful status
bra.s exit2
NoDos:
moveq.l #100,d0 * Exit thread if no dos.library
bra.s exit2 *
exit:
_exit:
XCEXIT:
move.l 4(SP),d0 * Extract return code
exit2:
move.l d0,-(a7)
move.l AbsExecBase.W,a6
move.l DOSBase(A4),a1
callsys CloseLibrary * Close Dos library
*------ this rts sends us back to DOS:
tst.l WBenchMsg(a4) * Did we run from Workbench
beq.s ExitToDOS * If not, skip WB cleanup
move.l SysBase(A4),a6 *
callsys Forbid * Stop Workbench unloading us too soon
move.l WBenchMsg(a4),a1 *
callsys ReplyMsg * Return our startup msg
ExitToDOS:
move.l (A7)+,D0
movea.l _StackPtr(a4),SP * Restore stack ptr
movem.l (a7)+,d1-d6/a0-a6
rts
*-----------------------------------------------------------------------
* Global definitions
*
csect __MERGED,1,,2,2
xdef NULL,SysBase,LoadAddress,DOSBase
xdef _oserr,_OSERR,_ONBREAK
xdef _ProgramName,_StackPtr,_base,WBenchMsg
NULL dc.l 0
_base dc.l 0
_oserr equ *
_OSERR dc.l 0
_ONBREAK dc.l 0
SysBase dc.l 0
LoadAddress dc.l 0
_StackPtr dc.l 0
DOSBase dc.l 0
_ProgramName dc.l 0
WBenchMsg dc.l 0
DOSName dc.b 'dos.library',0
END